﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Windows;

namespace 解析BT种子文件
{
    public class BencodeParser
    {
        private byte[] _data;
        private int _index;

        public BencodeParser(byte[] data)
        {
            _data = data;
        }

        public object Parse()
        {
            char prefix = (char)_data[_index];
            if (prefix == 'i') return ParseInteger();
            if (prefix == 'l') return ParseList();
            if (prefix == 'd') return ParseDictionary();
            if (char.IsDigit(prefix)) return ParseString();
            throw new InvalidDataException($"Unknown prefix: {prefix}");
        }

        private long ParseInteger()
        {
            _index++; // Skip 'i'
            int end = Array.IndexOf(_data, (byte)'e', _index);
            if (end == -1) throw new InvalidDataException("Integer not terminated by 'e'");
            string number = Encoding.UTF8.GetString(_data, _index, end - _index); // 修改为 UTF-8
            _index = end + 1; // Move past 'e'
            return long.Parse(number);
        }

        private string ParseString()
        {
            int colon = Array.IndexOf(_data, (byte)':', _index);
            if (colon == -1) throw new InvalidDataException("String length not found");
            int length = int.Parse(Encoding.UTF8.GetString(_data, _index, colon - _index)); // 修改为 UTF-8
            _index = colon + 1;
            string result = Encoding.UTF8.GetString(_data, _index, length); // 修改为 UTF-8
            _index += length;
            return result;
        }

        private List<object> ParseList()
        {
            _index++; // Skip 'l'
            var list = new List<object>();
            while (_data[_index] != 'e')
            {
                list.Add(Parse());
            }
            _index++; // Skip 'e'
            return list;
        }

        private Dictionary<string, object> ParseDictionary()
        {
            _index++; // Skip 'd'
            var dict = new Dictionary<string, object>();
            while (_data[_index] != 'e')
            {
                string key = (string)Parse();
                object value = Parse();
                dict[key] = value;
            }
            _index++; // Skip 'e'
            return dict;
        }
    }

    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.Loaded += MainWindow_Loaded;
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            string filePath = @"C:\Users\16602\Desktop\kali-linux-2019.3-amd64.iso.torrent";
            byte[] data = File.ReadAllBytes(filePath);
            var parser = new BencodeParser(data);

            try
            {
                var result = parser.Parse();
                if (result is Dictionary<string, object> torrentInfo)
                {
                    Debug.WriteLine("Torrent parsed successfully.");
                    DisplayDictionary(torrentInfo);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error parsing torrent file: " + ex.Message);
            }
        }
        private static void DisplayDictionary(Dictionary<string, object> dict, string indent = "")
        {
            foreach (var kvp in dict)
            {
                Console.WriteLine($"{indent}{kvp.Key}:");
                if (kvp.Value is Dictionary<string, object> subDict)
                {
                    DisplayDictionary(subDict, indent + "  ");
                }
                else if (kvp.Value is List<object> list)
                {
                    Console.WriteLine($"{indent}  [List of {list.Count} items]");
                    foreach (var item in list)
                    {
                        if (item is Dictionary<string, object> innerDict)
                        {
                            DisplayDictionary(innerDict, indent + "    ");
                        }
                        else
                        {
                            Console.WriteLine($"{indent}    {item}");
                        }
                    }
                }
                else
                {
                    Console.WriteLine($"{indent}  {kvp.Value}");
                }
            }
        }

    }
}
